package ar.com.seminario.model;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import ar.com.seminario.common.domain.entity.Identifiable;
import ar.com.seminario.model.enumerados.EstadoSolicitud;
import ar.com.seminario.model.enumerados.NecesidadIngreso;

/**
 * Detalla la solicitud de ingreso.
 * 
 * @author Pablo Lamas
 * 
 */
@Entity
@Table(name = "solicitud_ingreso")
public class SolicitudIngreso implements Identifiable<Long> {

	/**
	 * Identificador de la entidad.
	 */
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name = "id", nullable = false)
	private Long id;

	/**
	 * Estado de la solicitud.
	 */
	@Column(name = "estado_solicitud_id", nullable = false)
	private Long estadoSolicitudId;

	/**
	 * Perfil asociado a la busqueda.
	 */
	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "perfil_id", nullable = true)
	private Perfil perfil;

	/**
	 * Motivo de la busqueda.
	 */
	@Column(name = "necesidad_ingreso_id", nullable = false)
	private Long necesidadIngresoId;

	/**
	 * Detalle de Otra Necesidad de Ingreso.
	 */
	@Column(name = "otra_necesidad_ingreso", nullable = true)
	private String otraNecesidadIngreso;

	/**
	 * Detalle del proyecto asignado.
	 */
	@Column(name = "proyecto_asignado", nullable = false)
	private String proyectoAsignado;

	/**
	 * Cantidad vacantes para el puesto.
	 */
	@Column(name = "cantidad_vacantes", nullable = false)
	private Integer cantidadVacantes;

	/**
	 * Observaciones.
	 */
	@Column(name = "observaciones", nullable = false)
	private String observaciones;

	/**
	 * Oficina que requiere el ingreso.
	 */
	@ManyToOne
	@JoinColumn(name = "oficina_id", nullable = false)
	private Oficina oficina;

	/**
	 * Lista de entrevistas.
	 */
	@OneToMany(mappedBy = "solicitudIngreso", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
	private List<Entrevista> entrevistas;

	/**
	 * Fecha de incorporacion esperada.
	 */
	@Column(name = "fecha_esperada_incorporacion", nullable = false)
	private Date fechaEsperadaIncorporacion;

	/**
	 * Fecha de solicitud.
	 */
	@Column(name = "fecha_solicitud", nullable = false)
	private Date fechaSolicitud;

	/**
	 * El gerente que solicita el ingreso.
	 */
	@Column(name = "gerente_solicitante", nullable = false)
	private String gerenteSolicitante;

	/**
	 * El nombre del Superior Directo.
	 */
	@Column(name = "superior_directo", nullable = false)
	private String superiorDirecto;

	/**
	 * Fecha de inicio de la busqueda.
	 */
	@Column(name = "fecha_inicio_busqueda", nullable = true)
	private Date fechaInicioBusqueda;

	/**
	 * Descripcion de la justificacion de porque se cierra o se rechaza la
	 * solicitud.
	 */
	@Column(name = "justificacion", nullable = true)
	private String justificacion;

	/**
	 * Lista de entrevistas.
	 */
	@OneToMany(mappedBy = "solicitudIngreso", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
	private List<SolicitudCandidato> solicitudesCandidatos;

	/**
	 * Constructor por defecto.
	 */
	public SolicitudIngreso() {

	}

	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Integer getCantidadVacantes() {
		return cantidadVacantes;
	}

	public void setCantidadVacantes(Integer cantidadVacantes) {
		this.cantidadVacantes = cantidadVacantes;
	}

	public String getObservaciones() {
		return observaciones;
	}

	public void setObservaciones(String observaciones) {
		this.observaciones = observaciones;
	}

	public Date getFechaEsperadaIncorporacion() {
		return fechaEsperadaIncorporacion;
	}

	public void setFechaEsperadaIncorporacion(Date fechaEsperadaIncorporacion) {
		this.fechaEsperadaIncorporacion = fechaEsperadaIncorporacion;
	}

	public Date getFechaSolicitud() {
		return fechaSolicitud;
	}

	public void setFechaSolicitud(Date fechaSolicitud) {
		this.fechaSolicitud = fechaSolicitud;
	}

	public Date getFechaInicioBusqueda() {
		return fechaInicioBusqueda;
	}

	public void setFechaInicioBusqueda(Date fechaInicioBusqueda) {
		this.fechaInicioBusqueda = fechaInicioBusqueda;
	}

	public EstadoSolicitud getEstadoSolicitud() {
		return EstadoSolicitud.fromId(this.estadoSolicitudId);
	}

	public void setEstadoSolicitud(EstadoSolicitud estadoSolicitud) {
		if (estadoSolicitud != null) {
			this.estadoSolicitudId = estadoSolicitud.getId();
		} else {
			this.estadoSolicitudId = null;
		}
	}

	public boolean addEntrevista(Entrevista entrevista) {

		if (this.entrevistas == null) {
			this.entrevistas = new ArrayList<Entrevista>();
		}

		if (entrevista != null) {
			entrevista.setSolicitudIngreso(this);
		}

		return this.entrevistas.add(entrevista);
	}

	public boolean removeEntrevista(Entrevista entrevista) {

		if (this.entrevistas == null) {
			return (false);
		} else {
			return this.entrevistas.remove(entrevista);
		}
	}

	public List<Entrevista> getAllEntrevistas() {

		if (this.entrevistas == null) {
			return null;
		} else {
			return Collections.unmodifiableList(this.entrevistas);
		}
	}

	public List<SolicitudCandidato> getSolicitudesCandidatos() {
		return solicitudesCandidatos;
	}

	public void addSolicitudesCandidatos(SolicitudCandidato solicitudCandidato) {
		if (solicitudCandidato != null) {
			this.solicitudesCandidatos.add(solicitudCandidato);
			solicitudCandidato.setSolicitudIngreso(this);
		}
	}

	public NecesidadIngreso getNecesidadIngreso() {
		return NecesidadIngreso.fromId(necesidadIngresoId);
	}

	public void setNecesidadIngresoId(NecesidadIngreso necesidadIngreso) {
		if (necesidadIngreso != null) {
			this.necesidadIngresoId = necesidadIngreso.getId();
		}
	}

	public String getOtraNecesidadIngreso() {
		return otraNecesidadIngreso;
	}

	public void setOtraNecesidadIngreso(String otraNecesidadIngreso) {
		this.otraNecesidadIngreso = otraNecesidadIngreso;
	}

	public String getProyectoAsignado() {
		return proyectoAsignado;
	}

	public void setProyectoAsignado(String proyectoAsignado) {
		this.proyectoAsignado = proyectoAsignado;
	}

	public Oficina getOficina() {
		return oficina;
	}

	public void setOficina(Oficina oficina) {
		this.oficina = oficina;
	}

	public String getGerenteSolicitante() {
		return gerenteSolicitante;
	}

	public void setGerenteSolicitante(String gerenteSolicitante) {
		this.gerenteSolicitante = gerenteSolicitante;
	}

	public String getSuperiorDirecto() {
		return superiorDirecto;
	}

	public void setSuperiorDirecto(String superiorDirecto) {
		this.superiorDirecto = superiorDirecto;
	}

	public Perfil getPerfil() {
		return perfil;
	}

	public void setPerfil(Perfil perfil) {
		this.perfil = perfil;
	}

	public String getJustificacion() {
		return justificacion;
	}

	public void setJustificacion(String justificacion) {
		this.justificacion = justificacion;
	}

}
